﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Framework;
using SchemaMonitor;
using System.Data;
using System.IO;
using System.Drawing;
using SchemaMonitor.json;
using System.Xml;
using SchemaMonitor.xml;
using SchemaMonitor;

namespace DetectDuplicates
{
	class Program
	{

        static void Main(string[] args)
		{
			//SyncData();
			//Console.ReadLine();


			CDataSrc localPhotos  = new CSqlClient("server=.;database=JewBookPhotos;Trusted_Connection=True;");
			CDataSrc localFacebk  = new CSqlClient("server=.;database=FacebookRecycleBin;Trusted_Connection=True;");
			CDataSrc remotePhotos = new CWebSrcBinary("http://recyclebin.mikeconnellministries.com/webservices/FBDatasrc.ashx");
			CDataSrc remoteFacebk = new CWebSrcBinary("http://recyclebin.mikeconnellministries.com/datasrc.ashx");
			
			//LOCAL
			//CDataSrc.Default = localFacebk;
			//CConfig.Photos = localPhotos;

			//REMOTE
			CDataSrc.Default = remoteFacebk;
			CConfig.Photos = remotePhotos;



			//var existing = new CTextMessage(remoteFacebk).SelectAll();
			//var doc = CSmsList.Load(@"C:\Users\picas\Downloads\sms-20170703232117.xml");
			//foreach (var i in doc)
			//{
			//	if (existing.GetById(i.Date) != null)
			//		continue;

			//	i.Save(remoteFacebk);

			//	var num = doc.IndexOf(i) + 1;
			//	var s = string.Concat(num, " of ", doc.Count, " (", (100.0 * num / doc.Count).ToString("n0"), "%)");
			//	Console.WriteLine(s);
			//}
			//Console.ReadLine();







            //DUPLICATES

			CPhotoHash.FindAndStoreMatches(Int16.MaxValue, false, -1);
			Console.WriteLine("Finished");
			Console.ReadLine();

			//Histogram
			var histX = CPhotoHash.HistX();

			//Known thumbs
			Console.WriteLine("Loading x-cors...");
			var xcor = new Dictionary<Guid, Dictionary<Guid, int>>();
			Parallel.ForEach(CPhotoHash.Cache.Ids, i => 
			{
				if (xcor.Count < 1000)
				{
					var d = CPhotoHash.GetCorr(i);
					if (null != d)
						lock(xcor)
							xcor.Add(i, d);
				}
			});

			Console.WriteLine("Convert to Hist");
			var histY = CPhotoHash.ConvertCorrToHist(histX, xcor);
			xcor = null;
			var final = CPhotoHash.FlattenHist(histX, histY);
			var count = 1;
			foreach (var i in final)
			{
				var t = i.Key;
				var i1 = t.Item1;
				var i2 = t.Item2;
				foreach (var j in i.Value)
				{
					var g1 = j.Item1;
					var g2 = j.Item2;
				}
				var s = string.Concat(i1.ToString("n0"), "\t*", count, "\t => \t", i2.ToString("n0"), ": ", i.Value.Count.ToString("n0"));
				Console.WriteLine(s);
			}

			Console.ReadLine();


		}


		private static void SyncData()
		{

			CDataSrc localPhotos = new CSqlClient("server=.;database=JewBookPhotos;Trusted_Connection=True;");
			CDataSrc localFacebk = new CSqlClient("server=.;database=FacebookRecycleBin;Trusted_Connection=True;");
			CDataSrc remotePhotos = new CWebSrcBinary("http://recyclebin.mikeconnellministries.com/webservices/FBDatasrc.ashx");
			CDataSrc remoteFacebk = new CWebSrcBinary("http://recyclebin.mikeconnellministries.com/datasrc.ashx");

			SyncPhotos(localPhotos, remotePhotos);
			SyncPhotos2(localPhotos, remotePhotos);

			var tt = new CTagType(remotePhotos).SelectAll();
			var mt = new CMetaTag(remotePhotos).SelectAll();
			var l1 = new CLabel_OneToOne(remotePhotos).SelectAll();
			var lm = new CLabel(remotePhotos).SelectAll();
			var im = new CImageMatching(remotePhotos).SelectAll();
			var id = new CImageMatchedButDifferent(remotePhotos).SelectAll();

			new CImageMatching(localPhotos).DeleteAll();
			new CImageMatchedButDifferent(localPhotos).DeleteAll();

			CConfig.Photos = localPhotos;
			CLabel_OneToOne.Cache = null;
			CLabel.Cache = null;
			CMetaTag.Cache = null;
			CTagType.Cache = null;
			


			CConfig.Photos = localPhotos;
			foreach (var i in im) new CImageMatching(i, localPhotos).Save();
			foreach (var i in id) new CImageMatchedButDifferent(i, localPhotos).Save();
			foreach (var i in tt)
				CTagType.Cache.GetOrCreate(i.TypeName, i.TypeAppId, i.TagIsOneToOne);

			foreach (var i in mt)
			{
				var typeR = tt.GetById(i.TagTypeId);
				var typeL = CTagType.Cache.GetOrCreate(typeR.TypeName, typeR.TypeAppId, typeR.TagIsOneToOne);
				CMetaTag.Cache.GetOrCreate(i.TagName, typeL.TypeId);
			}
			foreach (var i in l1)
			{
				var tagR = mt.GetById(i.LabelTagId);
				var typeR = tt.GetById(tagR.TagTypeId);
				var typeL = CTagType.Cache.GetOrCreate(typeR.TypeName, typeR.TypeAppId, typeR.TagIsOneToOne);
				var tagL = CMetaTag.Cache.GetOrCreate(tagR.TagName, typeL.TypeId);

				var j = CLabel_OneToOne.Cache.GetById(i.LabelGuid, typeL.TypeId) ?? new CLabel_OneToOne(localPhotos);
				j.LabelGuid = i.LabelGuid;
				j.LabelTagId = tagL.TagId;
				j.LabelTypeId = typeL.TypeId;
				j.Save();
			}
			CLabel.Cache = null;
			var llm = new CLabel(localPhotos).SelectAll();
			foreach (var i in lm)
			{
				var tagR = mt.GetById(i.LabelTagId);
				var typeR = tt.GetById(tagR.TagTypeId);
				var typeL = CTagType.Cache.GetOrCreate(typeR.TypeName, typeR.TypeAppId, typeR.TagIsOneToOne);
				var tagL = CMetaTag.Cache.GetOrCreate(tagR.TagName, typeL.TypeId);

				var j = llm.GetById(i.LabelGuid, tagL.TagId) ?? new CLabel(localPhotos);
				j.LabelGuid = i.LabelGuid;
				j.LabelTagId = tagL.TagId;
				j.Save();
			}
		}
		private static void SyncPhotos(CDataSrc localPhotos, CDataSrc remotePhotos)
		{
			var loc = new CPhotoHash(localPhotos).SelectDistinctGuid("PhotoMd5");
			var rem = new CPhotoHash(remotePhotos).SelectDistinctGuid("PhotoMd5");

			var diff = CDiffLogic.Diff(rem, loc);
			foreach (var i in diff.TargetOnly)
				localPhotos.DeleteWhere(CPhotoHash.TABLE_NAME, new CCriteria(CPhotoHash.PRIMARY_KEY_NAME, i));

			var pi = new CPagingInfo(10, 0);
			var page = CUtilities.Page(diff.SourceOnly, pi.PageSize, pi.PageIndex);
			while (page.Count > 0)
			{
				var orig = new CPhotoHash(remotePhotos).SelectWhere(CPhotoHash.PRIMARY_KEY_NAME, ESign.IN, page);
				foreach (var i in orig)
				{
					var p = new CPhotoHash(i, localPhotos);
					p.PhotoBlob = i.GetBlob();
					p.PhotoThumb48x48_Int16ProtoGz = i.GetThumb();
					p.PhotoThumbMD5 = i.PhotoThumbMD5;
					p.Save();
				}
				pi.PageIndex++;
				page = CUtilities.Page(diff.SourceOnly, pi.PageSize, pi.PageIndex);
			}
		}

		private static void SyncPhotos2(CDataSrc localPhotos, CDataSrc remotePhotos)
		{
			var loc = new CPhoto(localPhotos).SelectDistinct("ID");
			var rem = new CPhoto(remotePhotos).SelectDistinct("ID");

			var diff = CDiffLogic.Diff(rem, loc);
			foreach (var i in diff.TargetOnly)
				localPhotos.DeleteWhere(CPhotoHash.TABLE_NAME, new CCriteria(CPhoto.PRIMARY_KEY_NAME, long.Parse(i)));

			var pi = new CPagingInfo(10, 0);
			var page = CUtilities.Page(diff.SourceOnly, pi.PageSize, pi.PageIndex);
			while (page.Count > 0)
			{
				var orig = new CPhoto(remotePhotos).SelectWhere(CPhoto.PRIMARY_KEY_NAME, ESign.IN, page);
				foreach (var i in orig)
				{
					var p = new CPhoto(i, localPhotos);
					p.Save();
				}
				pi.PageIndex++;
				page = CUtilities.Page(diff.SourceOnly, pi.PageSize, pi.PageIndex);
			}
		}
	}
}
